﻿using System.IO;
using System.Modules.Utility.DTO.ULS.EventArguments;
using Microsoft.SharePoint.Utilities;

namespace System.Modules.Utility.DTO.ULS.Monitoring
{    
    class LogMonitor: ILogMonitor
    {
        readonly FileTail _fileTail;
        readonly string _folderPath;
        readonly LogDirectoryWatcher _watcher;
        bool _firstLine;

        public event EventHandler<LogEntryDiscoveredEventArgs> LogEntryDiscovered = delegate { };

        public LogMonitor(string folderPath)
        {
            if (!Directory.Exists(folderPath))
                throw new ArgumentException("Directory does not exist.", folderPath);
            this._folderPath = folderPath;
            _fileTail = new FileTail();
            _fileTail.LineDiscovered += new EventHandler<LineDiscoveredEventArgs>(fileTail_LineDiscovered);
            _watcher = new LogDirectoryWatcher(folderPath);
            _watcher.FileCreated += new EventHandler<FileCreatedEventArgs>(watcher_FileCreated);            
        }

        public void Start()
        {
            _watcher.Start();
            string filePath = SPUtility.GetLastAccessedFile(_folderPath);
            if (filePath != null)
                _fileTail.Start(filePath);
        }

        public void Stop()
        {
            _watcher.Stop();
            _fileTail.Stop();
        }

        void watcher_FileCreated(object sender, FileCreatedEventArgs e)
        {
            _fileTail.Stop();
            _firstLine = true;
            _fileTail.Start(e.Filename);
        }

        void fileTail_LineDiscovered(object sender, LineDiscoveredEventArgs e)
        {
            if (!String.IsNullOrEmpty(e.Line.Trim()) && !_firstLine)
            {
                var entry = LogEntry.Parse(e.Line);
                if (entry != null)
                    LogEntryDiscovered(this, new LogEntryDiscoveredEventArgs() { LogEntry = entry });
            }
            _firstLine = false;
        }

        #region IDisposable Members

        public void Dispose()
        {
            _fileTail.Stop();
            _watcher.Dispose();
        }

        #endregion
    }
}
